package boogie.game;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JPanel;

/**
 *
 * @author Boogie
 */
public abstract class Game extends JPanel implements Runnable {

    private Map<String, GameState> states;
    private BufferedImage buffer;
    public final int width, height;
    public volatile int FPS = 32;
    private volatile Thread gameLoop;
    private volatile boolean paused;
    private volatile GameState currentState;
    

    public Game(int width, int height) {
        this.width = width;
        this.height = height;
        states = new HashMap<>();
        buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    }

    public synchronized void start() {
        gameLoop = new Thread(this);
        gameLoop.start();
    }

    public synchronized void stop() {
        gameLoop = null;
        currentState.onStop();
    }

    public synchronized void pause() {
        paused = true;
        currentState.onPause();

    }

    public synchronized void resume() {
        paused = false;
        currentState.onResume();

    }

    public void addState(String name, GameState state) {
        state.onInit();
        state.setGame(this);
        states.put(name, state);
    }

    public GameState getCurrentState() {
        return currentState;
    }

    public void setCurrentState(GameState currentState) {
        if (this.currentState != null) {
            this.currentState.onPause();
        }
        this.currentState = currentState;
        this.currentState.onResume();

    }

    public GameState getState(String name) {
        return states.get(name);
    }

    public abstract void initStates();

    public void init() {
        this.requestFocus();
        initStates();

    }

    public void update() {
        currentState.onUpdate();
    }

    public void draw() {
        Graphics2D bufferG = buffer.createGraphics();
        bufferG.setColor(Color.BLACK);
        bufferG.fillRect(0, 0, width, height);
        currentState.onDraw(bufferG);
        Graphics g = this.getGraphics();
        g.drawImage(buffer, 0, 0, null);
        bufferG.dispose();
        g.dispose();
    }

    @Override
    public void run() {
        init();

        while (gameLoop == Thread.currentThread()) {
            if (!paused) {
                update();
            }
            draw();
            
            try {
                Thread.sleep(1000 / currentState.getFpsRate());
            } catch (InterruptedException ex) {
            }
        }
    }


    
    public boolean isPaused() {
        return this.paused;
    }
}
